#!/bin/bash
########################################################################
# script name:  update_code_by_archive.sh
# Used for:
# Author:       Martin Dumont
# Contributors:
# Version:      0.1
#
# (date format: date +'%Y/%m/%d')
#
# Date          Version Contributors    Modifications
# ----------    ------- ------------    -------------
# 2011/12/16    0.1     MDUMONT         initial
########################################################################
usage()
{
cat << STOP

usage: $0 [options] [ARG]

This script is used for ....

OPTIONS:
   -h               Hosts [all]
   -c               Commit (see commits with "git log --remotes=origin" or don't specify anything for latest commit )
   -r               Repository (sap|dispatch|files|web)
   -f               Force (don't ask for commit confirmation)

Ex.:
$0 -h sapbcp01 -c 74f7032384953d38c7fce0e36a8ceb7e20894a14 -r web
$0 -h qa -r sap -c 74f7032384953d38c7fce0e36a8ceb7e20894a14
$0 -h prd -r files
$0 -h saphrt01,saphrt02 -r files -c 74f7032384953d38c7fce0e36a8ceb7e20894a14
STOP
}
if [ `whoami` != root ]; then
	echo Please run this script as root or using sudo
	exit
fi
#######################################
# Get parameters
#######################################
while getopts h:c:r:f OPTION
do
        case $OPTION in
        h)
                HOSTS=$(/bin/echo $OPTARG | tr '[A-Z]' '[a-z]' | sed 's/,/ /g')
                ;;
        c)
                COMMIT=$(/bin/echo $OPTARG)
                ;;
        r)
                REPO=$(/bin/echo $OPTARG)
                ;;
		  f)
					 FORCE=yes
				    ;;
        \?)
                usage
                exit 1
                ;;
        *)
                usage
                exit 1
                ;;
        esac
done
#if [ $OPTIND = 1 ]; then usage; exit 1; fi
if [ -z "$HOSTS" ]; then HOSTS=localhost; fi
if [ -z "$REPO" ]; then REPO=sap.git; fi
#######################################
# Variables and environnement
#######################################
BAENV=$(dirname `which $0`)/loadenv.sh
if [ -f $BAENV ]; then . $BAENV; else echo "No env library ($BAENV)"; exit 1; fi
MAINDIR=/var/code
DEPOT=/central/depot/code
ORIGINREPO=$ORIGIN/$REPO/
SSH_OPTS=" -x -q -o ConnectTimeout=15 -o BatchMode=yes -o StrictHostKeyChecking=no -o LogLevel=fatal"
#######################################
CLONE=/tmp/$REPO
rm -rf $CLONE 2>&1 > /dev/null
cd /tmp
/bin/sudo -u git /usr/bin/git clone $ORIGINREPO $CLONE
if [ -z "$COMMIT" ]; then COMMIT=$(echo "cd $CLONE && /usr/bin/git log --no-decorate --oneline -n 1 | cut -d' ' -f1" | /bin/sudo -u git /bin/bash); fi
echo -n "Verifying commit $COMMIT ..."
if ! echo "cd $CLONE && /usr/bin/git show $ORIGINREPO $COMMIT 2>&1 > /dev/null" | /bin/sudo -u git /bin/bash | grep -q $COMMIT; then echo ok; else echo "doesn't exist"; exit 1; fi
if [ -z "$FORCE" ]
	then
	echo; echo "Showing commit: "
	echo "+------------------------------------------------------------------+"
	(echo "cd $CLONE && /usr/bin/git show $COMMIT | sed 's/^/| /g'" | /bin/sudo -u git /bin/bash)
	echo "+------------------------------------------------------------------+"
	echo; read -p "Is this the commit you want to push? [y/n]: "
	if [ "$REPLY" != "y" ]
	then
		echo
		read -p "Do you want to see the list of commits? [y/n]: "
		if [ "$REPLY" = "y" ];then echo "cd $CLONE && /usr/bin/git log --no-decorate --oneline" | /bin/sudo -u git /bin/bash; fi
		exit 1
	fi
fi
DIR=$MAINDIR/${REPO}.$COMMIT
#######################################
# MAIN
#######################################
\/bin/sudo -u git rm -rf $CLONE 2>&1 > /dev/null
echo; echo Extracting commit $COMMIT to $DIR; echo
NEWHOSTLIST=$(checkhost $HOSTS | grep -v Verifying)
for HOSTNAME in $NEWHOSTLIST
do
	cat <<-EOF | if [ "$HOSTNAME" != "localhost" ]; then /bin/su - saunix -c "ssh $SSH_OPTS $HOSTNAME \"cat | sudo /bin/bash\""; else cd /tmp; cat | /bin/sudo /bin/bash; fi
		umask 022
		if [ ! -d $MAINDIR ]; then mkdir -p $MAINDIR; fi
		chmod 755 $MAINDIR
		if [ -d $DIR ]; then \rm -rf $DIR; fi
		mkdir -m 755 -p $DIR && chown git $DIR
		cd $DIR
		echo "/usr/bin/git archive --format=tar --remote=$ORIGINREPO $COMMIT | tar -xmf - && echo $COMMIT > .version" | sudo -u git /bin/bash
		chown -R root $DIR && chmod -R 755 $DIR
		cd $MAINDIR
		if [ -d $MAINDIR/${REPO} ]; then \rm -rf $MAINDIR/${REPO}; fi
		BASE=$(echo $REPO | sed 's/.git//')
		if [ -h \${BASE} ]; then rm \${BASE}; fi
		ln -fs $DIR \${BASE}
		ls -1td $MAINDIR/* | grep $REPO | tail -n +4 | xargs \rm -rf
		if [ -f $DIR/.version ]
		then
			/bin/echo "$HOSTNAME: Commit $COMMIT has been pushed to $MAINDIR/\${BASE} (linked to $DIR)"
		else
			/bin/echo "$HOSTNAME: Something went wrong, I don't see any $DIR/.version file"
		fi
	EOF
done
echo
#######################################
exit 0
